package online.heycm.platform.rocketmq.publisher;

import java.io.IOException;
import lombok.extern.slf4j.Slf4j;
import online.heycm.platform.common.tools.Jackson;
import online.heycm.platform.rocketmq.common.entity.Event;
import online.heycm.platform.rocketmq.common.entity.EventState;
import online.heycm.platform.rocketmq.common.handler.LocalTransactionHandler;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;

/**
 * 事件事务监听
 *
 * @author heycm
 * @since 2023/12/2 20:36
 */
@Slf4j
public class EventTransactionListener implements TransactionListener {

    @Override
    public LocalTransactionState executeLocalTransaction(Message message, Object o) {
        try {
            Event event = this.messageToEvent(message);
            LocalTransactionHandler localTransactionHandler = LocalTransactionHandlerRegistry.get(event);
            EventState commit = localTransactionHandler.executeLocalTransaction(event);
            return EventState.COMMIT == commit ? LocalTransactionState.COMMIT_MESSAGE
                    : LocalTransactionState.ROLLBACK_MESSAGE;
        } catch (Exception e) {
            e.printStackTrace();
            log.info("execute local transaction [{}] error: {}", message.getTransactionId(), e.getMessage(), e);
        }
        return LocalTransactionState.ROLLBACK_MESSAGE;
    }

    @Override
    public LocalTransactionState checkLocalTransaction(MessageExt messageExt) {
        try {
            Event event = this.messageToEvent(messageExt);
            LocalTransactionHandler localTransactionHandler = LocalTransactionHandlerRegistry.get(event);
            EventState check = localTransactionHandler.checkLocalTransaction(event);
            return EventState.COMMIT == check ? LocalTransactionState.COMMIT_MESSAGE
                    : LocalTransactionState.ROLLBACK_MESSAGE;
        } catch (Exception e) {
            e.printStackTrace();
            log.info("check local transaction [{}] error: {}", messageExt.getTransactionId(), e.getMessage(), e);
        }
        return LocalTransactionState.ROLLBACK_MESSAGE;
    }

    private Event messageToEvent(Message message) throws IOException {
        return Jackson.toObject(message.getBody(), Event.class);
    }
}
